%-*-coding: utf-8 -*- 
%abs-guide-chpater01.tex
\chapter{Shell编程}
\begin{quote}
\small\textit{
No programming language is perfect. There is not even a single best language; there are only languages well suited or perhaps poorly suited for particular purposes.
\begin{flushright}
--Herbert Mayer
\end{flushright}
}
\end{quote}

对任何一个希望成为熟练的系统管理员的人来说，对shell脚本的良好理解都是必须的，无论他们是否希望实际上取写一个脚本文件。考虑一个Linux机器的启动过程，它执行了/etc/rc.d脚本来存储系统的配置和设置的服务，对这类启动脚本的深入理解是分析系统行为修改这个脚本的基础。

脚本编程并不是一门难以学习的技艺，因为脚本总是可以拆分成更小的块结构，而且要学习的Shell的操作符和选项也只有很少一部分。Shell的语法是简洁直观的，并且只有很少的一部分规则需要学习。绝大部分脚本第一次就可以正常的工作，而且即使调试一个长一些的脚本也是很直观的。

\begin{quote}
在70年代，BASIC语言使那些对计算机有一定了解的人能够在早先一代的微型计算机上写程序。几十年后，脚本语言使任何对Linux有了解的人在更强大的计算机上执行工作。
\end{quote}

一个 shell 脚本是一个类似于小吃店的(quick and dirty)方法,在你使用原型设计一个复杂的应用的时候。在工程开发的第一阶段，即使从功能中取得很有限的一个子集放到 shell脚本中来完成往往都是非常有用的。使用这种方法，程序的结果可以被测试和尝试运行，并且在处理使用诸如 C/C++，Java，Perl或者 Python 语言编写的最终代码前，主要的缺陷和陷阱往往就被发现了。

Shell 脚本遵循典型的 UNIX 哲学，就是把大的复杂的工程分成小规模的子任务，并且把这些部件和工具组合起来。许多人认为这种办法更好一些，至少这种办法比使用那些新一代的高性能高集成的语言更愉悦,更适合解决问题。比如 Perl 就是这种能干任何事能适合任何人的语言,但是代价就是你需要强迫自己使用这种语言来思考解决问题的办法。

根据 Herbert Mayer的说法，“一个有用的语言需要数组、指针以及构建数据结构所需的泛型机制。” 根据这些标准，Shell脚本看起来是是“不太有用”了。或许，也可能不是这样

%\noindent
\fbox{
\begin{minipage}[c]{0.85\textwidth}
哪些情况不应该使用 Shell
\begin{itemize}
\item 资源密集型任务，尤其是有速度方面的考量时。
\item 过程包含大量的数据运算，特别是浮点运算，高精度的运算，复数运算时（使用 C++ 或者 FORTRAN 来代替）
\item 需要跨平台移植性（使用 C 或者 Java ）
\item 复杂应用程序，需要使用结构化的编程语言
（对变量、函数原型的类型检查等等）
\item 你拿来决定公司未来的重要应用程序
\item 安全性比较重要的场合，你需要保证系统的完整性，并避免入侵、破解和破坏
\item 子模块间依赖性较强的项目
\item 需要扩展的文件操作（Bash 只能进行串行文件访问，
并且只能笨拙的逐行访问）
\item 需要原生的多维数组支持
\item 需要数据结构，比如链表或者树
\item 需要生成/操作图形或者图形化界面
\item 需要直接访问硬件
\item 需要端口或者套接字 I/O 支持
\item 需要使用较老代码编译的库或者接口
\item 所有的闭源程序（Shell 脚本把你的源代码开放给整个世界）
\end{itemize}

如果以上所列条目中的任意一项符合，那么考虑一个更加强大的脚本语言吧，比如 Perl，Tcl，Python，Ruby。或者一个编译型的语言，比如 C，C++，或者 Java。即便如此，使用 Shell脚本来构建原型仍然是软件开发中很有用的步骤。
\end{minipage}
}

我们将会使用 Bash，Bash是“Bourne-Again shell”的缩写。并且Bash也是 Stephen Bourene的经典的 Bourene shell的双关语。对大多数 Unix 环境来说，Bash是事实上的 Shell 脚本编程的标准。本书中的大部分原则都可以等价的转换为其他的 Shell 环境，比如 Korn Shell（Bash 从其中继承了一些特性），或者 C Shell 以及它的变种。（C Shell 编程并不被推荐，因为存在一些特定的内在问题，可以参考 Tom Christiansen 1993年10月发表在 Usenet post 上的文章。）

接下来的内容是对 shell 脚本编程的介绍。它很大程度上依赖于例子来阐释 Shell 的各种特性。例子中的脚本都在尽可能的范围内进行了测试,并且其中的一些将使用在真实的生活中.读者可以运行这些例子脚本(使用 scriptname.sh或者 scriptname.bash 的形式)，并给这些脚本执行权限(chmod u+rx scriptname)，然后执行它们，看看发生了什么。如果存档的脚本不可用,那么就从本书的 HTML,pdf 或者text 的发行版本中把它们拷贝粘贴出来。考虑到这些脚本中的内容在我们还没解释它之前就被列在这里，可能会影响读者的理解，这就需要读者暂时忽略这些内容. 
 
除非特别声明，下文中的示例代码是由本书的作者写作完成的。
